import { rBus, rStatus, rStore } from './prototype'

type storeArrType = rStore<any>[]

type rStoreProtoType_clearMethods = (methodKeys: Array<string>, isAsync: boolean) => void

type rStoreProtoType_pushState = (str: string, fun: Function) => void

type rStoreProtoType_listState_AND_actions = { [name: string]: Function }

type rStoreProtoType_changeState = (str: string, value?: Array<any>) => any

type rStoreProtoType_asyncPushState = (str: string, fun: Function) => void

type rStoreProtoType_asyncChangeState = (str: string, value?: Array<any>) => Promise<Function>

type rStoreProtoType_reactive_callback_function_ = Array<Function>

type rStoreProtoType_the_react_instance_array_ = Array<{ keys: Array<string>, _react: typeReact }>

type rStoreProtoType_responseCallback = (fun: Function) => void

type rStoreProtoType_bindData = (dataKay: Array<string>, _instance: typeReact) => void

type rStoreProtoType_unBindData = (keyArr: Array<string>, _instance: typeReact) => void

type rStoreProtoType_clearData = (dataKeys: Array<string>) => void

type rStoreProtoType_changeData<T> = (obj: Partial<T>) => void

type ProxyType_store_bindData_AND_unBindData = (dataKeysArr: Array<string>, storeName: string) => void

type ProxyType_store_changStateSumType = (name: string, valueArr: Array<any>, storeName: string) => any

type clearMethodsFun_Type = rStoreProtoType<any>['function_that_requires_asynchronous_processing'] | rStoreProtoType<any>['listState']

type rstoreAnyType = rStoreProtoType<any>

type rStoreProtoOptionsType<T> = Omit<rStoreProtoType<T>, 'storeName'>

type rStoreProtoType_type_sum<T> = Omit<rStoreProtoOptionsType<T>, 'data'>

interface DataType { [name: string]: any }

interface newStore<T> {
    data: T
    name: string
    actions: (store: rStoreProtoType<T>) => { [a: string]: Function }
}

interface newBus {
    name: string
    actions?: (store: rBusProtoType) => { [a: string]: Function }
}

interface newStatus<T> {
    data: T
    name: string
    actions: (store: rStatusProtoType<T>) => { [a: string]: Function }
}

interface Setting<T> {
    Data: T
}

interface storeOptions<T> {
    Data: T
}

interface asyncBusType {
    [name: string]: {
        _promise: Promise<any> | Function
        _resolve: (fun: Function) => any
        _isAsync: boolean
    }
}

interface typeReact { forceUpdate: Function }

interface rBusProtoType {
    clearMethods: rStoreProtoType_clearMethods
    pushState: rStoreProtoType_pushState
    changeState: rStoreProtoType_changeState
    asyncPushState: rStoreProtoType_asyncPushState
    asyncChangeState: rStoreProtoType_asyncChangeState
    listState: rStoreProtoType_listState_AND_actions
    function_that_requires_asynchronous_processing: asyncBusType
}

type StatusArrType = Array<rStatus<any>>

type BusArrType = Array<rBus>

interface rStatusProtoType<T> {
    data: T
    bindData: rStoreProtoType_bindData
    unBindData: rStoreProtoType_unBindData
    clearData: rStoreProtoType_clearData
    changeData: rStoreProtoType_changeData<T>
    responseCallback: rStoreProtoType_responseCallback
    reactive_callback_function_: rStoreProtoType_reactive_callback_function_
    the_react_instance_array_: rStoreProtoType_the_react_instance_array_
    actions: rStoreProtoType_listState_AND_actions
}



interface rStoreProtoType<T> {
    readonly storeName: string | undefined
    data: T
    bindData: rStoreProtoType_bindData
    unBindData: rStoreProtoType_unBindData
    clearData: rStoreProtoType_clearData
    changeData: rStoreProtoType_changeData<T>
    reactive_callback_function_: rStoreProtoType_reactive_callback_function_
    the_react_instance_array_: rStoreProtoType_the_react_instance_array_
    actions: rStoreProtoType_listState_AND_actions
    clearMethods: rStoreProtoType_clearMethods
    pushState: rStoreProtoType_pushState
    changeState: rStoreProtoType_changeState
    asyncPushState: rStoreProtoType_asyncPushState
    asyncChangeState: rStoreProtoType_asyncChangeState
    listState: rStoreProtoType_listState_AND_actions
    function_that_requires_asynchronous_processing: asyncBusType
    responseCallback: rStoreProtoType_responseCallback
}

interface ProxyType_store {
    data: {
        [name: string]: any
    }
    actions: {
        [name: string]: rStoreProtoType_listState_AND_actions
    }
    bindData: ProxyType_store_bindData_AND_unBindData
    unBindData: ProxyType_store_bindData_AND_unBindData
    responseCallback: (fun: Function, storeName: string) => void
    changeData: (data: { [name: string]: any }, storeName: string) => void
    clearData: (dataKeys: Array<string>, storeName: string) => void
    pushState: (str: string, fun: Function, storeName: string) => void
    changeState: ProxyType_store_changStateSumType
    clearMethods: (mothodsNameArr: Array<string>, isAsync: boolean, storeName: string) => void
    asyncPushState: (str: string, fun: Function, storeName: string) => void
    asyncChangeState: ProxyType_store_changStateSumType
}

interface ProxyType_bus {
    actions?: {
        [name: string]: rStoreProtoType_listState_AND_actions
    }
    pushState: (str: string, fun: Function, storeName: string) => void
    changeState: ProxyType_store_changStateSumType
    clearMethods: (mothodsNameArr: Array<string>, isAsync: boolean, storeName: string) => void
    asyncPushState: (str: string, fun: Function, storeName: string) => void
    asyncChangeState: ProxyType_store_changStateSumType
}

interface ProxyType_status {
    data: {
        [name: string]: any
    }
    actions: {
        [name: string]: rStoreProtoType_listState_AND_actions
    }
    bindData: ProxyType_store_bindData_AND_unBindData
    unBindData: ProxyType_store_bindData_AND_unBindData
    responseCallback: (fun: Function, storeName: string) => void
    changeData: (data: { [name: string]: any }, storeName: string) => void
    clearData: (dataKeys: Array<string>, storeName: string) => void
}

interface ProxyType_proxStores {
    [string: string]: rStore<any>
}

interface ProxyType_proxBus {
    [string: string]: rBusProtoType
}

interface ProxyType_proxStatus {
    [string: string]: rStatus<any>
}

interface ProxyTypes {
    rStore: ProxyType_store
    rStatus: ProxyType_status
    rBus: ProxyType_bus
}

export type {
    rStoreProtoType,
    newStore,
    storeOptions,
    Setting,
    storeArrType,
    asyncBusType,
    clearMethodsFun_Type,
    rstoreAnyType,
    typeReact,
    DataType,
    ProxyType_store,
    ProxyType_proxStores,
    ProxyTypes,
    rStoreProtoOptionsType,
    rStoreProtoType_type_sum,
    newBus,
    rBusProtoType,
    rStatusProtoType,
    newStatus,
    BusArrType,
    StatusArrType,
    ProxyType_proxBus,
    ProxyType_proxStatus,
    ProxyType_status,
    ProxyType_bus
}
